#pragma once

#include "Misc/CommonMacros.h"
#include "VectorBase.h"

class CType;

// non-template vesion of TVector, can force convert to/from TVector<T> ,for example: TVector<int>  a; CReflectableVector b= (CReflectableVector) a;
// because they have same memory layout
// this is used for reflection system, because reflection system can not handle template type
class WHENGINE_API CReflectableVector : public CVectorBase<void>
{
public:
    CReflectableVector() = default;

    CReflectableVector(CType* InDataType,const CReflectableVector& Other);

    ~CReflectableVector();

    CReflectableVector& operator=(CReflectableVector&& Other);

    //make sure capcity is enough
    void Reserve(CType* InDataType, uint64_t NewCapacity);
    //make sure capcity== Num
    void ShrinkToFit(CType* InDataType);
    void Resize(CType*InDataType, uint64_t NewSize,bool ShrinkCapacity=true);
    void Clear(CType*InDataType, bool ShrinkCapacity=true) ;

    //add a default value of InDataType
    void AddDefault(CType* InDataType);

    void Add(CType* InDataType, const void* InValue);

    void InsertDefault(CType* InDataType, uint64_t Index);
    void Insert(CType* InDataType, uint64_t Index, const void* InValue);

    void RemoveAt(CType* InDataType, uint64_t Index,bool ShrinkCapacity=true);
    
    void* At(CType* InDataType, uint64_t Index) const;
    void SetAt(CType* InDataType, uint64_t Index, const void* InValue);


    uint64_t GetHashCode(CType* InDataType) const;
    bool IsEqual(CType* InDataType, const CReflectableVector& Other) const;

    struct SDataAndSize
    {
        void* Data;
        uint64_t Size;
    };

    SDataAndSize GetDataAndSize(CType* InDataType) const;
    void SetDataAndSize(CType* InDataType, const void* InData, uint64_t InSize);
    //TODO add Find() function, but it is not easy to implement, because we need to compare two value

};